#include <iostream>
#include <string>
#include <functional>
#include <sys/socket.h>
#include <sys/types.h>
#include <strings.h>
#include <netinet/in.h>
#include <stdlib.h>
#include "log.hpp"
#include "dic.hpp"

namespace Socket_Module
{
    using func_t = std::function<std::string(std::string)>;

    class Socket
    {
        public:
            Socket(int port,func_t func)
                :_port(port)
                ,_isrunning(false)
                ,_func(func)
            {
                ;
            }
            void Init()
            {
                _sockfd = socket(AF_INET,SOCK_DGRAM,0);

                struct sockaddr_in local;

                socklen_t len = sizeof(local);
                // 清零
                bzero(&local,sizeof(local));
                // 地址家族AF_INET(IPV4)
                local.sin_family = AF_INET;
                // 端口号
                local.sin_port = htons(_port);
                // 任何IP都不忽略。
                local.sin_addr.s_addr = INADDR_ANY;
                // 绑定
                int n = bind(_sockfd,(struct sockaddr*)&local,len);

                if(n != 0)
                {
                    LogSpace::Logger::LogMessage(LogSpace::LogLevel::FATAL,"Socket",1,LogSpace::log) << "Socket Fail!";
                    exit(1);
                }
            }
            void Start()
            {
                _isrunning = true;

                while(_isrunning)
                {
                    char message[1024];

                    struct sockaddr_in receive;
                    socklen_t len = sizeof(receive);
                    // 毕竟是系统调用不是库函数不会主动在末尾加0。
                    // 收消息
                    ssize_t n = recvfrom(_sockfd,message,sizeof(message) - 1,0,(struct sockaddr*)&receive,&len);

                    if(n > 0)
                    {
                        message[n] = 0;
                        
                        // 处理要发送的消息。
                        std::string send = _func(message);

                        // 发送消息。
                        sendto(_sockfd,send.c_str(),send.size(),0,(struct sockaddr*)&receive,sizeof(receive));
                        std::cout << send << std::endl;
                    }
                }
            }
            ~Socket()
            {
                ;
            }
        private:
            int _sockfd;
            uint16_t _port;
            // std::string _ip; // 用的是字符串风格，点分十进制, "192.168.1.1"
            bool _isrunning;

            func_t _func; // 服务器的回调函数，用来进行对数据进行处理
    };
}